package com.winit.openapi.sms;

import com.winit.common.query.Page;
import com.winit.common.spi.SPIException;
import com.winit.common.spi.context.CommandContext;
import com.winit.common.spring.SpringMessageLocator;
import com.winit.common.utils.Dates;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.sms.common.DateUtils;
import com.winit.openapi.sms.common.SmsUtils;
import com.winit.openapi.util.DateUtil;
import com.winit.sms.spi.common.command.CodeCommand;
import com.winit.sms.spi.common.command.IdCommand;
import com.winit.sms.spi.common.constant.Constants;
import com.winit.sms.spi.common.constant.Constants.CreditAcctProductLine;
import com.winit.sms.spi.common.vo.PageVo;
import com.winit.sms.spi.wallet.bill.BillService;
import com.winit.sms.spi.wallet.bill.command.QueryBillByCustomerCodeAndTypeCommand;
import com.winit.sms.spi.wallet.bill.vo.BillVo;
import com.winit.sms.spi.wallet.cashaccount.CashAccountService;
import com.winit.sms.spi.wallet.creditaccount.CreditAccountService;
import com.winit.sms.spi.wallet.creditaccount.CreditCounterFeeService;
import com.winit.sms.spi.wallet.creditaccount.CreditRepaymentService;
import com.winit.sms.spi.wallet.creditaccount.command.*;
import com.winit.sms.spi.wallet.creditaccount.vo.*;
import com.winit.sms.spi.wallet.creditaccounttype.CreditAccountypeService;
import com.winit.sms.spi.wallet.creditaccounttype.command.QueryCreditAccountTypeByTypeCommand;
import com.winit.sms.spi.wallet.creditaccounttype.vo.CreditAccountTypeVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 信用账户
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * keke.xu 	1.0  		2016年1月11日 	Created
 * 
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping("/sms/creditAccount")
public class CreditAccountController extends BaseController {

    private static Logger           logger = LoggerFactory.getLogger(CreditAccountController.class);
    @Resource
    private CreditAccountService    creditAccountService;
    @Resource
    private CreditRepaymentService  creditRepaymentService;
    @Resource
    private CreditAccountypeService creditAccountypeService;
    @Resource
    private BillService             billService;
    @Resource
    private CashAccountService      cashAccountService;
    @Resource
    private CreditCounterFeeService creditCounterFeeService;

    /**
     * 查询信用账户信息
     *
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryCreditAcct")
    public String queryCreditAcct(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        IdCommand command = SmsUtils.toJavaObject(requestMsg.getData(), IdCommand.class);
        CreditAccountVo queryCreditAcct = creditAccountService.queryCreditAcct(command);
        responseMsg.setData(queryCreditAcct);
        return SUCCESS;
    }

    /**
     * 信用账户明细分页查询
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/pageCreditAccountLine")
    public String pageCreditAccountLine(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryCreditAccountLineCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryCreditAccountLineCommand.class);
        PageVo pageVo = SmsUtils.SetPageParams(requestMsg.getData());
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        command.setPageVo(pageVo);
        if (null != command.getTransactionDateEnd()) {
            command.setTransactionDateEnd(DateUtil.spliceDate(command.getTransactionDateEnd()));
        }
        Page<CreditAccountLineVo> page = creditAccountService.pageCreditAccountLine(command);
        Map<String, Object> data = SmsUtils.setPageData(page);
        //        data = buildSumAmount(data, command);
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 根据客户id查询所有已开通账户余额信息
     *
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryCreditAcctByCustomid")
    public String queryCreditAcctByCustomid(@ModelAttribute RequestMsg requestMsg,
                                            @ModelAttribute ResponseMsg responseMsg) {
        try {
        	QueryCreditAccountByProducLineCommand command = new QueryCreditAccountByProducLineCommand();
            Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
            if (bpartner == null) {
                logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
                return ERROR;
            }
            command.setCustomerCode(bpartner.getValue());
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>queryCreditAcctByCustomid:" + command.toString());
            List<CreditAccountVo> creditAccountVoList = creditAccountService.queryCreditAcctsByCustomCode(command);
            Map<String, Object> paramsMap = new HashMap<String, Object>();

            CodeCommand codeCommand = new CodeCommand();
            codeCommand.setCode(bpartner.getValue());
            for (CreditAccountVo creditAccountVo : creditAccountVoList) {
                String productLine = creditAccountVo.getProductLine();
                //判断是不是未生效

                bildOverDueCreditAcct(creditAccountVo);
                if (creditAccountVo.getEffectiveDate().after(new Date())) {
                    creditAccountVo.setStatus("3");
                }
                dealIspCreditAcct(creditAccountVo, bpartner.getcBpartnerId());
                creditAccountVo.setQuota(creditAccountVo.getStandardQuotad());
                paramsMap.put(productLine, creditAccountVo);// 信用账户 ：当前账户余额
            }
            responseMsg.setData(paramsMap);
		} catch (SPIException e) {
			logger.error("queryCreditAcctByCustomid-----》根据客户id查询所有已开通账户余额信息异常",e);
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
		}
        return SUCCESS;
    }

    private void bildOverDueCreditAcct(CreditAccountVo vo) throws SPIException{
        BigDecimal returnAmount = BigDecimal.ZERO;// 还款金额
        String returnDate = null;//最后还款日期yyyy-MM-dd(前端要求字符串)
        int overdueDay = 0; //逾期多少天(当前日期对比最后还款日期)
        //        QueryCreditAccountTypeByTypeCommand queryCreditAccountTypeByTypeCommand = new QueryCreditAccountTypeByTypeCommand();
        //        queryCreditAccountTypeByTypeCommand.setCreditAcctType(vo.getCreditAcctType());
        //        CreditAccountTypeVo creditAccountTypeVo = creditAccountypeService.queryCreditAccountTypeByType(queryCreditAccountTypeByTypeCommand);

        //查询上一期账单
        QueryBillByCustomerCodeAndTypeCommand queryBillByCustomerCodeAndTypeCommand = new QueryBillByCustomerCodeAndTypeCommand();
        queryBillByCustomerCodeAndTypeCommand.setCustomerCode(vo.getCustomerCode());
        queryBillByCustomerCodeAndTypeCommand.setProductLine(vo.getProductLine());
        List<BillVo> billVoList = billService.queryLatestRecordByCustomerCodeAndType(queryBillByCustomerCodeAndTypeCommand);
        if (!billVoList.isEmpty()) {
            BillVo billVo = billVoList.get(0);
            if (billVo != null) {
                returnAmount = billVo.getBorrowAmount().add(billVo.getReturnAmount());
                if (returnAmount.compareTo(BigDecimal.ZERO) == -1) {
                    returnAmount = returnAmount.abs();
                } else {
                    returnAmount = BigDecimal.ZERO;
                }
                //                Date tempDate = billVo.getBilldate();
                //                tempDate = DateUtils.addDate(tempDate, Integer.valueOf(creditAccountTypeVo.getReturnDay()));
                Date tempDate = billVo.getDueDate();
                overdueDay = DateUtils.diffDate(tempDate, new Date());
                returnDate = DateUtils.format(tempDate);
                // 多期逾期未还
                BigDecimal totalReturnAmout = BigDecimal.ZERO;
                totalReturnAmout = totalReturnAmout.add(billVo.getReturnAmount());
                //当期未逾期,往后再查两期有没有逾期
                if (new Date().getTime() > billVo.getDueDate().getTime()) {
                    if (billVoList.size() > 1) {
                        billVo = billVoList.get(1);
                        totalReturnAmout = totalReturnAmout.add(billVo.getReturnAmount());
                        if (billVo.getBorrowAmount().add(totalReturnAmout).compareTo(BigDecimal.ZERO) == -1) {
                            if (billVoList.size() > 2) {
                                billVo = billVoList.get(2);
                                totalReturnAmout = totalReturnAmout.add(billVo.getReturnAmount());
                                if (billVo.getBorrowAmount().add(totalReturnAmout).compareTo(BigDecimal.ZERO) == -1) {
                                    vo.setDoubleOverFlag("1");
                                }
                            }
                        }
                    }
                } else {
                    //当期已逾期,再往后查一期
                    if (billVoList.size() > 1) {
                        billVo = billVoList.get(1);
                        totalReturnAmout = totalReturnAmout.add(billVo.getReturnAmount());
                        if (billVo.getBorrowAmount().add(totalReturnAmout).compareTo(BigDecimal.ZERO) == -1) {
                            vo.setDoubleOverFlag("1");
                        }
                    }
                }
            }
        } else {
            returnAmount = null;
        }

        QueryCreditAccountLogByCreditIdCommand queryCreditAccountLogByCreditIdCommand = new QueryCreditAccountLogByCreditIdCommand();
        queryCreditAccountLogByCreditIdCommand.setCreditAcctId(vo.getId());
        CreditAccountLogVo creditAccountLogVo = creditAccountService.queryCreditAccountLogByFirst(queryCreditAccountLogByCreditIdCommand);
        if (creditAccountLogVo != null) {
            vo.setEffectiveDate(creditAccountLogVo.getEffectiveDate());// 合同有效期开始日期
            vo.setExpireDate(creditAccountLogVo.getExpireDate());
        }

        vo.setReturnAmount(returnAmount);
        vo.setReturnDate(returnDate);
        vo.setOverdueDay(overdueDay);
    }

    private void dealIspCreditAcct(CreditAccountVo creditAccountVo, Long cbpartnerId) {
        if (null == creditAccountVo || null == creditAccountVo.getStandardValidDate()) {
            return;
        }

        // 当前时间
        Date currentDate = new Date();
        // ISP信用额度到期时间
        //        Date overdueDate = creditAccountVo.getStandardValidDate();
        //ISP信用额度到期时间改为合同到期时间
        Date overdueDate = creditAccountVo.getExpireDate();
        if (overdueDate.after(currentDate)) {
            // 未过期则设置是否过期状态为N
            creditAccountVo.setIsOverdue(SmsUtils.STATUS_N);

            // 不足一天的算一天，日期相减后加1
            // 用额度到期日减去当前时间得到多少天后过期。如果在两周内过期，设置两周内过期状态为Y并设置多少天后过期。
            int overdueDays = DateUtils.diffDate(currentDate, overdueDate) + 1;
            if (overdueDays <= 14) {
                creditAccountVo.setIsSoonOverdue(SmsUtils.STATUS_Y);
                creditAccountVo.setOverdueDays(overdueDays);
            }
        } else {
            // 已过期则设置是否过期状态为Y，是否两周后过期状态为N
            creditAccountVo.setIsOverdue(SmsUtils.STATUS_Y);
            creditAccountVo.setIsSoonOverdue(SmsUtils.STATUS_N);
        }
    }

    /**
     * 根据客户id查询单个已开通账户余额信息
     *
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryCreditAcctByProductLine")
    public String queryCreditAcctByCustomidAndProducLine(@ModelAttribute RequestMsg requestMsg,
                                                         @ModelAttribute ResponseMsg responseMsg) {
        try {
        	Map<String, Object> paramsMap = new HashMap<String, Object>();
            BigDecimal returnAmount = BigDecimal.ZERO;// 欠款金额
            String _accountPeriod = null; // 账期（账单日）
            String _returnDay = null; // 最后还款天
            String _returnDate = null; //最后还款日期
            String billDate = null; //账单日期
            int overdueDay = 0;
            BillVo billVo = null; //账单
            QueryCreditAccountByProducLineCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
                QueryCreditAccountByProducLineCommand.class);
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>queryCreditAcctByCustomidAndProducLine:" + command.toString());
            Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
            if (bpartner == null) {
                logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
                return ERROR;
            }
            String customerCode = bpartner.getValue();
            command.setCustomerCode(customerCode);
            CreditAccountVo creditAccountVo = null;
            List<CreditAccountVo> vo = creditAccountService.queryCreditAcctIsExist(command);
            if (vo != null && vo.size() > 0) {
                creditAccountVo = vo.get(0);
            }

            if (creditAccountVo != null) {
            	//查询另外一个账户
                QueryCreditAccountByProducLineCommand otherCommand = new QueryCreditAccountByProducLineCommand();
                CreditAccountVo otherCreditAccountVo = null;
                //另外账号的账户余额
                BigDecimal otherTransactionTotal = BigDecimal.ZERO;
                if (StringUtils.equals(CreditAcctProductLine.ISP.getVal(), command.getProductLine())) {
                    otherCommand.setProductLine(CreditAcctProductLine.OWHS.getVal());
                } else if (StringUtils.equals(CreditAcctProductLine.OWHS.getVal(), command.getProductLine())) {
                    otherCommand.setProductLine(CreditAcctProductLine.ISP.getVal());
                }
                otherCommand.setCustomerCode(customerCode);
                List<CreditAccountVo> otherVo = creditAccountService.queryCreditAcctIsExist(otherCommand);
                if (otherVo != null && otherVo.size() > 0) {
                    otherCreditAccountVo = otherVo.get(0);
                }
                if (null != otherCreditAccountVo) {
            		//可转金额 = if(账户余额 > 可用余额) ? 可用余额 : 账户余额
                	if(otherCreditAccountVo.getTransactionTotal().compareTo(otherCreditAccountVo.getAvailableBalance()) == 1){
                		//可用余额比账户余额小，取可用余额
                		if(BigDecimal.ZERO.compareTo(otherCreditAccountVo.getAvailableBalance()) == -1){
                			otherTransactionTotal = otherCreditAccountVo.getAvailableBalance();
                		}
                	}else{
                		if(BigDecimal.ZERO.compareTo(otherCreditAccountVo.getTransactionTotal()) == -1){
                			//取账户余额
                			otherTransactionTotal = otherCreditAccountVo.getTransactionTotal();
                		}
                	}
                    paramsMap.put("otherTransactionTotal", otherTransactionTotal);
                }
                
                QueryCreditAccountLogByCreditIdCommand queryCreditAccountLogByCreditIdCommand = new QueryCreditAccountLogByCreditIdCommand();
                queryCreditAccountLogByCreditIdCommand.setCreditAcctId(creditAccountVo.getId());
                CreditAccountLogVo creditAccountLogVo = creditAccountService.queryCreditAccountLogByFirst(queryCreditAccountLogByCreditIdCommand);
                if (null != creditAccountLogVo) {
                    creditAccountVo.setEffectiveDate(creditAccountLogVo.getEffectiveDate());// 合同有效期开始日期
                    creditAccountVo.setExpireDate(creditAccountLogVo.getExpireDate());
                }

                String creditAcctType = creditAccountVo.getCreditAcctType();
                if (StringUtils.isNotBlank(creditAcctType)) {
                    QueryCreditAccountTypeByTypeCommand queryCreditAccountTypeByTypeCommand = new QueryCreditAccountTypeByTypeCommand();
                    queryCreditAccountTypeByTypeCommand.setCtx(command.getCtx());
                    queryCreditAccountTypeByTypeCommand.setCreditAcctType(creditAcctType);
                    CreditAccountTypeVo creditAccountTypeVo = creditAccountypeService.queryCreditAccountTypeByType(queryCreditAccountTypeByTypeCommand);
                    if (creditAccountTypeVo != null) {
                    	creditAccountVo.setDailyInterestRate(creditAccountTypeVo.getDailyInterestRate());	//日利率
                        creditAccountVo.setExpenseRate(creditAccountTypeVo.getExpenseRate());				//逾期手续费
                        
                        Long accountPeriod = creditAccountTypeVo.getAccountPeriod();// 账期
                        if (accountPeriod == 0) {
                            _accountPeriod = SpringMessageLocator.getMessage(ErrorCode.EVERY_MONTH, command.getCtx()
                                .getLocale());
                        } else if (accountPeriod == 1) {
                            _accountPeriod = SpringMessageLocator.getMessage(ErrorCode.MONDAY, command.getCtx().getLocale());
                        } else if (accountPeriod == 2) {
                            _accountPeriod = SpringMessageLocator.getMessage(ErrorCode.SIXTEEN_EVERY_MONTH,
                                command.getCtx().getLocale());
                        }
                        _returnDay = getReturnDay(_returnDay, creditAccountTypeVo, command);
                        
                        //判断信用账户是否开通额度信息
                        if (Constants.OWHS_PRESUPPOSITION_ACCOUNT.equals(creditAcctType)
                            || Constants.ISP_PRESUPPOSITION_ACCOUNT.equals(creditAcctType)) {
                            paramsMap.put("isQuota", 0); //没额度
                        } else {
                            paramsMap.put("isQuota", 1); //有额度
                        }

                        // 上期账单应还款金额
                        QueryBillByCustomerCodeAndTypeCommand queryBillByCustomerCodeAndTypeCommand = new QueryBillByCustomerCodeAndTypeCommand();
                        queryBillByCustomerCodeAndTypeCommand.setCustomerCode(customerCode);
                        queryBillByCustomerCodeAndTypeCommand.setProductLine(creditAccountVo.getProductLine());
                        List<BillVo> billVoList = billService.queryLatestRecordByCustomerCodeAndType(queryBillByCustomerCodeAndTypeCommand);
                        if (!billVoList.isEmpty()) {
                            billVo = billVoList.get(0);
                            if (billVo != null) {
                                returnAmount = billVo.getBorrowAmount().add(billVo.getReturnAmount());
                                overdueDay = DateUtils.diffDate(billVo.getDueDate(), new Date());
                                _returnDate = DateUtils.formatHHmm(billVo.getDueDate());
                                billDate = DateUtils.formatHHmm(billVo.getBilldate());
                                paramsMap.put("billDate", billDate);// 生成账单的日期
                                
                                //修复 BUG/40364 账单中和opc中的待还金额为负数，应为正数
                                BigDecimal borrowAmount = billVo.getBorrowAmount();		//账单金额
                                paramsMap.put("borrowAmount", borrowAmount.compareTo(BigDecimal.ZERO) < 0 ? borrowAmount.abs() : borrowAmount);
                            }
                        } else {
                            returnAmount = BigDecimal.ZERO;
                        }
                    }
                }
                // 合同有效期
                if (creditAccountLogVo != null) {
                    paramsMap.put("effectiveDate", Dates.formatDate(creditAccountLogVo.getEffectiveDate(), "yyyy-MM-dd"));// 合同有效期开始日期
                    paramsMap.put("expireDate", DateUtils.formatHHmm(creditAccountLogVo.getExpireDate())); // 合同有效期结束日期
                }
                //到期天数
                int overdueDays = DateUtils.diffDate(new Date(), creditAccountVo.getExpireDate()) + 1;
                creditAccountVo.setOverdueDays(overdueDays);

                BigDecimal availableBalance = BigDecimal.ZERO;
                if (creditAccountVo.getTransactionTotal().compareTo(BigDecimal.ZERO) >= 0) {
                    availableBalance = creditAccountVo.getStandardQuotad();
                } else {
                    availableBalance = creditAccountVo.getTransactionTotal().add(creditAccountVo.getStandardQuotad());
                }

                paramsMap.put("creditAccount", creditAccountVo);// 当前账户余额(前端取可用额度)
                paramsMap.put("accountPeriod", _accountPeriod);// 账期（账单日）
                paramsMap.put("returnDay", _returnDay);// 最后还款日
                paramsMap.put("returnAmount", returnAmount.compareTo(BigDecimal.ZERO) < 0 ? returnAmount.abs() : BigDecimal.ZERO);//待还金额
                paramsMap.put("_returnDate", _returnDate);//最后还款日
                paramsMap.put("overdueDay", overdueDay);//已逾期多少天
                paramsMap.put("quota", creditAccountVo.getStandardQuotad());// 当前授信额度
                paramsMap.put("billVo", billVo); //账单对象
                paramsMap.put("availableBalance", availableBalance); //额度信息的可用额度
                paramsMap.put("creditAcctIsOpen", 1);
                responseMsg.setData(paramsMap);
            } else {
                //未开通账户
                paramsMap.put("creditAcctIsOpen", 0);
                responseMsg.setData(paramsMap);
            }
		} catch (SPIException e) {
			logger.error("queryCreditAcctByCustomidAndProducLine-----》根据客户id查询单个已开通账户余额信息异常",e);
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
		}
        return SUCCESS;
    }

    /**
     * 获取还款日
     * @param _returnDay
     * @param creditAccountTypeVo
     * @param command
     * @return
     */
    private String getReturnDay(String _returnDay, CreditAccountTypeVo creditAccountTypeVo,
                                QueryCreditAccountByProducLineCommand command) {
        Object[] msg = { creditAccountTypeVo.getReturnDay() };
        // 还款日类型 1:账单日+;2:下月;3:下周;4:第二周;5:第三周;6:第四周
        if (creditAccountTypeVo.getReturnType() == 1L) {
            if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.END_OF_MONTH, command.getCtx().getLocale());
            } else {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.DAY, msg, command.getCtx().getLocale());
            }
        } else if (creditAccountTypeVo.getReturnType() == 2L) {
            if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.THE_END_OF_NEXT_MONTH, command.getCtx()
                    .getLocale());
            } else {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.NEXT_MONTH, msg, command.getCtx().getLocale());
            }
        } else if (creditAccountTypeVo.getReturnType() == 3L) {
            if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.THE_END_OF_THE_MONTH_OF_NEXT_WEEK,
                    command.getCtx().getLocale());
            } else {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.NEXT_WEEK, msg, command.getCtx().getLocale());
            }
        } else if (creditAccountTypeVo.getReturnType() == 4L) {
            if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.THE_END_OF_THE_SECOND_WEEK_OF_THE_WEEK,
                    command.getCtx().getLocale());
            } else {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.SECOND_WEEKS, msg, command.getCtx()
                    .getLocale());
            }
        } else if (creditAccountTypeVo.getReturnType() == 5L) {
            if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.THE_END_THIRD_WEEKS, command.getCtx()
                    .getLocale());
            } else {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.THIRD_WEEKS, msg, command.getCtx().getLocale());
            }
        } else if (creditAccountTypeVo.getReturnType() == 6L) {
            if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.THE_END_OF_FOURTH_WEEKS, command.getCtx()
                    .getLocale());
            } else {
                _returnDay = SpringMessageLocator.getMessage(ErrorCode.FOURTH_WEEKS, msg, command.getCtx()
                    .getLocale());
            }
        }

        if (creditAccountTypeVo.getAccountPeriod() == 2) {
            Object[] msgTwo = { creditAccountTypeVo.getReturnDayTwo() };
            if (creditAccountTypeVo.getReturnTypeTwo() == 1L) {
                if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.END_OF_MONTH, command.getCtx()
                                     .getLocale());
                } else {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.DAY, msgTwo, command.getCtx()
                                     .getLocale());
                }
            } else if (creditAccountTypeVo.getReturnTypeTwo() == 2L) {
                if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.THE_END_OF_NEXT_MONTH, command.getCtx()
                                     .getLocale());
                } else {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.NEXT_MONTH, msgTwo, command.getCtx()
                                     .getLocale());
                }
            } else if (creditAccountTypeVo.getReturnTypeTwo() == 3L) {
                if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.THE_END_OF_THE_MONTH_OF_NEXT_WEEK,
                                     command.getCtx().getLocale());
                } else {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.NEXT_WEEK, msgTwo, command.getCtx()
                                     .getLocale());
                }
            } else if (creditAccountTypeVo.getReturnTypeTwo() == 4L) {
                if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.THE_END_OF_THE_SECOND_WEEK_OF_THE_WEEK,
                                     command.getCtx().getLocale());
                } else {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.SECOND_WEEKS, msgTwo, command.getCtx()
                                     .getLocale());
                }
            } else if (creditAccountTypeVo.getReturnTypeTwo() == 5L) {
                if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.THE_END_THIRD_WEEKS, command.getCtx()
                                     .getLocale());
                } else {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.THIRD_WEEKS, msgTwo, command.getCtx()
                                     .getLocale());
                }
            } else if (creditAccountTypeVo.getReturnTypeTwo() == 6L) {
                if (creditAccountTypeVo.getReturnDay().equals("-1")) {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.THE_END_OF_FOURTH_WEEKS,
                                     command.getCtx().getLocale());
                } else {
                    _returnDay = _returnDay
                                 + SpringMessageLocator.getMessage(ErrorCode.or, command.getCtx().getLocale())
                                 + SpringMessageLocator.getMessage(ErrorCode.FOURTH_WEEKS, msgTwo, command.getCtx()
                                     .getLocale());
                }
            }
        }
        return _returnDay;
    }

    /**
     * 信用交易明细导出
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/exportCreditAccountLine")
    public String exportCreditAccountLine(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryCreditAccountLineCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryCreditAccountLineCommand.class);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        if (null != command.getTransactionDateEnd()) {
            command.setTransactionDateEnd(DateUtil.spliceDate(command.getTransactionDateEnd()));
        }
        String path = null;
        try {
            path = creditAccountService.exportCreditAccountLine(command);
            logger.info("信用交易明细导出路径：{}", path);
        } catch (SPIException e) {
            logger.error(e.getMessage());
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            responseMsg.setData(com.winit.sms.spi.common.constant.Constants.UPLOAD_FA);
            return ERROR;
        }
        responseMsg.setData(path);
        return SUCCESS;
    }

    /**
     * 客户冻结信用账户交易明细
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/pageCreditAcctLine")
    public String pageCreditAcctLine(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryCreditAccountLineCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryCreditAccountLineCommand.class);
        PageVo pageVo = SmsUtils.SetPageParams(requestMsg.getData());
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        command.setPageVo(pageVo);
        if (null != command.getTransactionDateEnd()) {
            command.setTransactionDateEnd(DateUtil.spliceDate(command.getTransactionDateEnd()));
        }
        Page<CreditAccountLineVo> page = creditAccountService.pageCreditAcctLineByCustomerCode(command);
        if (page == null) {
            return SUCCESS;
        }
        CreditAccountLineVo vo = creditAccountService.queryCreditAccountLineSum(command);

        if (vo == null) {
            return SUCCESS;
        }

        Map<String, Object> data = SmsUtils.setPageData(page);

        if (null == data) {
            data = new HashMap<String, Object>();
        }

        data.put("SumSourceAmount", vo.getSourceAmount() == null ? BigDecimal.ZERO : vo.getSourceAmount());
        data.put("SumStandardAmount", vo.getStandardAmount() == null ? BigDecimal.ZERO : vo.getStandardAmount());
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 信用未解冻交易明细导出
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/exportCreditLine")
    public String exportCreditLine(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryCreditAccountLineCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryCreditAccountLineCommand.class);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        if (null != command.getTransactionDateEnd()) {
            command.setTransactionDateEnd(DateUtil.spliceDate(command.getTransactionDateEnd()));
        }
        String path = null;
        try {
            path = creditAccountService.exportCreditLine(command);
            logger.info("信用交易明细导出路径：{}", path);
        } catch (SPIException e) {
            logger.error(e.getMessage());
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            responseMsg.setData(com.winit.sms.spi.common.constant.Constants.UPLOAD_FA);
            return ERROR;
        }
        responseMsg.setData(path);
        return SUCCESS;
    }

    // 将数字转化为大写
    public static String numToUpper(int num) {
        String u[] = { "一", "二", "三", "四", "五", "六", "日" };
        char[] str = String.valueOf(num).toCharArray();
        String rstr = "";
        for (int i = 0; i < str.length; i++) {
            rstr = rstr + u[Integer.parseInt(str[i] + "")];
        }
        return rstr;
    }

    /**
     * 卖家网站-授信手续费和逾期手续费汇总明细查询
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/pageCreditCounterFeeLine")
    public String pageCreditCounterFeeLine(@ModelAttribute RequestMsg requestMsg,
                                           @ModelAttribute ResponseMsg responseMsg) {
        QueryCreditCounterFeeLineCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryCreditCounterFeeLineCommand.class);
        PageVo pageVo = SmsUtils.SetPageParams(requestMsg.getData());
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        command.setPageVo(pageVo);

        if (null != command.getCounterfeeDateEnd()) {
            command.setCounterfeeDateEnd(DateUtil.spliceDate(command.getCounterfeeDateEnd()));
        }
        Page<CreditCounterFeeVo> page = creditCounterFeeService.pageCreditCounterFeeLine(command);
        if (null == page) {
            return SUCCESS;
        }
        Map<String, Object> data = SmsUtils.setPageData(page);
        if (null == data) {
            data = new HashMap<String, Object>();
        }
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 卖家网站-导出海外仓手续费明细
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/exportCreditCounterFeeLineOWHS")
    public String exportCreditCounterFeeLineOWHS(@ModelAttribute RequestMsg requestMsg,
                                                 @ModelAttribute ResponseMsg responseMsg) {
        QueryCreditCounterFeeLineCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryCreditCounterFeeLineCommand.class);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());

        if (null != command.getCounterfeeDateEnd()) {
            command.setCounterfeeDateEnd(DateUtil.spliceDate(command.getCounterfeeDateEnd()));
        }
        String path = null;
        try {
            path = creditCounterFeeService.exportCreditCounterFeeLineOWHS(command);
            logger.info("海外仓手续费明细导出路径：{}", path);
        } catch (SPIException e) {
            logger.error(e.getMessage());
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            responseMsg.setData(com.winit.sms.spi.common.constant.Constants.UPLOAD_FA);
            return ERROR;
        }
        responseMsg.setData(path);
        return SUCCESS;
    }

    /**
     * 创建默认的信用帐户
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/createDefaultCreditAcct")
    public String createCashAcct(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        CreateCreditAccountCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            CreateCreditAccountCommand.class);
        command.setCustomerCode(bpartner.getValue());
        try {
            creditAccountService.createDefaultCreditAcct(command);
        } catch (Exception e) {
            throw new ApiException(ErrorCode.SYSTEM_ERROR);
        }
        return SUCCESS;
    }

    /**
     * 卖家网站-根据客户编码查询已开通的信用账户信息
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryCreditAcctsByCustomCode")
    public String queryCreditAcctByCustomCode(@ModelAttribute RequestMsg requestMsg,
                                              @ModelAttribute ResponseMsg responseMsg) {
        QueryCreditAccountByProducLineCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryCreditAccountByProducLineCommand.class);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        Map<String, Object> map = new HashMap<String, Object>();
        //账单信息
        BillVo billVo = new BillVo();
        CreditAccountVo vo = new CreditAccountVo();
        //欠款金额
        BigDecimal returnAmount = BigDecimal.ZERO;
        //账户余额
        BigDecimal creditMoney = BigDecimal.ZERO;
        List<CreditAccountVo> list = creditAccountService.queryCreditAcctIsExist(command);
        if (null == list || list.size() == 0) {
            return ERROR;
        } else {
            vo = list.get(0);
            if(null != vo){
            	creditMoney = vo.getAvailableBalance();
            }
        }
        // 上期账单应还款金额
        QueryBillByCustomerCodeAndTypeCommand queryBillByCustomerCodeAndTypeCommand = new QueryBillByCustomerCodeAndTypeCommand();
        queryBillByCustomerCodeAndTypeCommand.setCustomerCode(command.getCustomerCode());
        queryBillByCustomerCodeAndTypeCommand.setProductLine(command.getProductLine());
        List<BillVo> billVoList = billService.queryLatestRecordByCustomerCodeAndType(queryBillByCustomerCodeAndTypeCommand);
        if (!billVoList.isEmpty()) {
            billVo = billVoList.get(0);
            if (billVo != null) {
                returnAmount = billVo.getBorrowAmount().add(billVo.getReturnAmount());
            }
        }

        map.put("creditMoney", creditMoney);	//账户可用余额
        map.put("returnAmount", returnAmount.negate());	//账户欠款金额
        responseMsg.setData(map);
        return SUCCESS;
    }

    /**
     * 卖家网站-根据客户编码查询已开通的信用账户信息
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/creditAccountIsOpen")
    public String creditAccountIsOpen(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryCreditAccountByProducLineCommand command = new QueryCreditAccountByProducLineCommand();
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        Map<String, Object> map = new HashMap<String, Object>();
        int creditAcctIsOpen = 0;
        //海外仓账户金额
        BigDecimal owhsAmount = BigDecimal.ZERO;
        //isp账户金额
        BigDecimal ispAmount = BigDecimal.ZERO;

        List<CreditAccountVo> list = creditAccountService.queryCreditAcctsByCustomCode(command);
        if (null != list && list.size() > 0) {
            for (CreditAccountVo vo : list) {
                if ("OWHS".equals(vo.getProductLine())) {
                    creditAcctIsOpen = 1;
                    owhsAmount = vo.getAvailableBalance();
                    map.put("owhsAmount", owhsAmount);
                } else {
                    creditAcctIsOpen = 2;
                    ispAmount = vo.getAvailableBalance();
                    map.put("ispAmount", ispAmount);
                }
            }
            if (list.size() == 2) {
                creditAcctIsOpen = 3;
                map.put("owhsAmount", owhsAmount);
                map.put("ispAmount", ispAmount);
            }
        }
        map.put("creditAcctIsOpen", creditAcctIsOpen);
        responseMsg.setData(map);
        return SUCCESS;
    }

    /**
     * 查询额度的生命周期
     *
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/queryCreditAccountQuotaCycle")
    public String queryCreditAccountQuotaCycle(@ModelAttribute RequestMsg requestMsg,
                                               @ModelAttribute ResponseMsg responseMsg) {
        IdCommand command = SmsUtils.toJavaObject(requestMsg.getData(), IdCommand.class);
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            List<CreditAccountLogVo> creditAccountLogList = creditAccountService.queryCreditAccountQuotaCycle(command);
            map.put("creditAccountLogList", creditAccountLogList);
            QueryCreditAccountLogByCreditIdCommand queryCreditAccountLogByCreditIdCommand = new QueryCreditAccountLogByCreditIdCommand();
            queryCreditAccountLogByCreditIdCommand.setCreditAcctId(command.getId());
            List<CreditAccountLogTimeVo> creditAccountLogTimeList = creditAccountService
                .queryCreditAcctLogTimeById(queryCreditAccountLogByCreditIdCommand);
            map.put("creditAccountLogTimeList", creditAccountLogTimeList);
        } catch (SPIException e) {
            logger.error("queryCreditAccountQuotaCycle查询额度的生命周期异常", e);
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
        }
        responseMsg.setData(map);
        return SUCCESS;
    }

}
